<?php
/**
 * appRain v 0.1.x
 *
 * LICENSE
 *
 * This source file is subject to the MIT license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.opensource.org/licenses/mit-license.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@apprain.com so we can send you a copy immediately.
 *
 * @copyright  Copyright (c) 2010 appRain, Team. (http://www.apprain.com)
 * @license    http://www.opensource.org/licenses/mit-license.php MIT license
 *
 * HELP
 *
 * Official Website
 * http://www.apprain.com/
 *
 * Download Link
 * http://www.apprain.com/download
 *
 * Documents Link
 * http ://www.apprain.com/docs
 */



/**
 * Admin Controller
 */
class developerController extends appRain_Base_Core
{
    public $name = 'Developer';

    /**
     * Admin index
     *
     * @parameter admin_flag string
     *
     * @return null
     */
    public function indexAction( $admin_flag = 'introduction')
    {
        $this->redirect('/admin/' . app::__def()->sysConfig('ADMIN_REDIRECTION'));
        exit;
    }

    /*
     * Developer file manager
     *
     * @parameter path string
     * @parameter file2edit string
     */
    public function editorAction( $path = "", $file2edit = NULL)
    {
        $this->setAdminTab('developer');

        $this->page_title = "Developer Page editor";
        $message = false;

        $path = isset( $path ) && ($path != "") ? $path : base64_encode( "" );

        $pathbase = App::load("Helper/Config")->get('basedir') . base64_decode( $path) ;

        # Directory listing
        $dir_listing = App::load("Helper/Utility")->getDirLising($pathbase);
        $this->set("base_path",base64_decode($path));
        $this->set("dir_listing",$dir_listing);


        if( isset( $file2edit ) )
        {
            $filepath = App::load("Helper/Config")->get('basedir') . base64_decode($path) . DS . base64_decode( $file2edit );

            if( !empty( $this->data ) && (is_writable($filepath)))
            {
                 App::Load("Helper/Utility")->savefilecontent( $filepath, $this->data['Editor']['content']);
            }

            if(!is_writable($filepath)) $message = $this->__("File is not writable!");

            $file2editcontent = App::Load("Helper/Utility")->fatchfilecontent($filepath);
            $this->set('file2editcontent',$file2editcontent);
            $this->set("filepath",$filepath);
        }

        $this->set("message",$message);
    }

    /**
     * View phpinfo()
     *
     * @return null
     */
    public function showmyphpinfoAction()
    {
       $this->setAdminTab('developer');
        $this->page_title = "PHP info";
    }


    /**
     * Manage appRain theme
     *
     * @parameter theme2install string
     * @return null
     */
    public function themeAction( $theme2install = NULL, $action = null)
    {
        // Sec Admin TAB
        $this->setAdminTab('developer');

        if(!empty($this->data))
        {
            $obj =  App::Module('Universal_Installer')
                        ->setSourceAutoDelete(true)
                        ->setDefaultInstallationPath(VIEW_PATH)
                        ->upload($this->data['Theme']['resourcefile'])
                        ->Install();
             if(empty($obj->errors))App::Module('Notification')->Push('Theme installed successfully');
             else App::Module('Notification')->Push($obj->errors,'Error');

			App::Module("Developer")->clearCache();
            $this->redirect("/developer/theme");
            exit;
        }
        else if ($action=='remove')
        {
            $obj =  App::Module('Universal_Installer')
                       ->setResourcePath( VIEW_PATH . DS . $theme2install)
                       ->Uninstall();

            App::Module('Notification')->Push('Theme Removed successfully');
			App::Module("Developer")->clearCache();
            $this->redirect("/developer/theme");
            exit;
        }

        if( isset($theme2install))
        {
            $new_theme = base64_decode($theme2install);
            $current_user_id = $this->getUserStatusId();

            $row = App::Model('Config')->find("fkey=$current_user_id AND soption='theme'");

            if( !empty( $row ))
            {
                $result = App::Model('Config')->save(
                                array(
                                        "Config" => array("svalue" =>$new_theme)),
                                        "soption='theme' AND fkey= $current_user_id"
                                );
            }
			App::Module('Notification')->Push('Theme installed successfully');
			App::Module("Developer")->clearCache();
            $this->redirect("/developer/theme");
            exit;
        }

        /*
         * Fetch themes
         */
        $theme_info = App::Load('Helper/Utility')->getDirLising(VIEW_PATH);
        $themes = Array();
        $themes_default = Array();
        foreach( $theme_info['dir'] as $val )
        {
            $path = VIEW_PATH . DS . $val['name'];

            if( file_exists("{$path}/definition/info.xml"))
            {
                $info =         App::Load("Helper/Utility")->fatchfilecontent("{$path}/definition/info.xml");
                $name =         App::Load("Helper/Utility")->get_value_by_tag_name($info,"<name>","</name>");
                $desc =         App::Load("Helper/Utility")->get_value_by_tag_name($info,"<description>","</description>");
                $author =       App::Load("Helper/Utility")->get_value_by_tag_name($info,"<author>","</author>");
                $author_uri =   App::Load("Helper/Utility")->get_value_by_tag_name($info,"<author_uri>","</author_uri>");

                $basepath = $path;

                $image = App::Load("Helper/Utility")->get_value_by_tag_name($info,"<image>","</image>");

                if( $name != "" && $desc != "" && $image != "" )
                {
                    $tmp = array
                                    (
                                        "name" => $val['name'],
                                        "title" => $name,
                                        "description"=> $desc,
                                        "image" => $image,
                                        "basepath"=>$basepath,
                                        'author' => $author,
                                        'author_uri' => $author_uri
                                    );

                    if( $this->theme == $val['name'] )
                    {
                         $themes_default =  $tmp;
                    }
                    else
                    {
                        $themes[] =  $tmp;
                    }
                }
            }
        }
        $this->set("themes",$themes);
        $this->set("action",$action);
        $this->set("themes_default",$themes_default);
    }

    /**
     * Import/Export Database
     * Output format is XML
     *
     * @return null
     */
    public function imexportAction( $action = null, $dta = NULL)
    {
        // Set tab and layout
        $this->setAdminTab('developer');
        $this->page_title = "Backup Database";

        if( $action == 'delete')
        {
            unlink(DATA . DS . "database/" . base64_decode($dta));
            App::Module('Notification')->Push($this->__("Deleted successfully"));
            $this->redirect('/developer/imexport/');
            exit;
        }

        $import_err = "";
        $backup_err = "";
        $restore_err = "";
        if( !empty( $this->data ))
        {
            if( isset($this->data['ImExport']['export']))
            {
                App::Load("Module/Dbimexport")->download = true;
                App::Load("Module/Dbimexport")->file_name = date("Y-m-d_H-i-s");
                App::Load("Module/Dbimexport")->export();
            }
            else if ( isset($this->data['ImExport']['import']) )
            {
                if(  $this->data['ImExport']['filename']['name'] == "")
                {
                    App::Module('Notification')->Push($this->__("Select a valid database file"),'Error');
                }
                else
                {
                   $raw_file = App::Load("Helper/Utility")->upload( $this->data['ImExport']['filename'], TEMP . DS );

                   App::Load("Module/Dbimexport")->import_path = TEMP . DS . $raw_file['file_name'];
                   App::Load("Module/Dbimexport")->import();

                   @unlink(App::Load("Module/Dbimexport")->import_path);
                   App::Module('Notification')->Push($this->__("Database Imported successfully"));
                }
            }
            else if ( isset($this->data['ImExport']['backup']))
            {
                App::Load("Module/Dbimexport")->file_name = $this->data['ImExport']['filename'];
                App::Load("Module/Dbimexport")->download_path = DATA . DS . "database";
                App::Load("Module/Dbimexport")->export();

                App::Module('Notification')->Push($this->__("Backup has creaded successfully."));
            }
            else if ( isset($this->data['ImExport']['restore']))
            {
                if( $this->data['ImExport']['file_name'] == "")
                {
                    App::Module('Notification')->Push($this->__("No Database file selected"),"Error");
                }
                else
                {
                    App::Load("Module/Dbimexport")->import_path = DATA . DS . "/database/{$this->data['ImExport']['file_name']}";
                    App::Load("Module/Dbimexport")->import();
                    App::Module('Notification')->Push("Database restorded successfully to {$this->data['ImExport']['file_name']}");
                }
            }

            $this->redirect('/developer/imexport/');
            exit;
        }

        $database_files = App::load("Helper/Utility")->getDirLising(DATA . DS . "database");
        $database_files['file'] = isset($database_files['file'])?$database_files['file'] : array();
        $database_files_paging = App::Helper('Utility')->array_paginator($database_files['file'],array('limit'=>10));

        $this->set("database_files_paging", $database_files_paging);
        $this->set("database_files", $database_files);
        $this->set("restore_err", $restore_err);
        $this->set("import_err", $import_err);
        $this->set("backup_err", $backup_err);
    }

    public function sys_configAction()
    {
        // Check authonitcation
        $this->setAdminTab('developer');

        $this->page_title = 'System Configuration';
        $message = "";
        $file_path = CONFIG_PATH . DS . "config.xml";
        $definition = array();
        $dom = new DOMDocument();
        $dom->load($file_path);

        if( isset($this->post['Button']['button_save']))
        {
            if( is_writeable($file_path))
            {
                $this->data['sconfig'] = isset($this->data['sconfig']) ? $this->data['sconfig'] : array();
                $options = $dom->getElementsByTagName('option');
                foreach( $options as $option )
                {
                    $name = $option->getAttribute('name');
                    $option->getElementsByTagName('value')->item(0)->nodeValue = '';

                    if( in_array($name, array_keys($this->data['sconfig'])))
                    {
                        $cdataNode = $dom->createCDATASection($this->data['sconfig'][$name]);
                        $option->getElementsByTagName('flag')->item(0)->nodeValue = 0;

                    }
                    else
                    {
                        $cdataNode = $dom->createCDATASection($option->getElementsByTagName('default')->item(0)->nodeValue);
                        $option->getElementsByTagName('flag')->item(0)->nodeValue = 1;
                    }

                    $option->getElementsByTagName('value')->item(0)->appendChild( $cdataNode );

                }

                App::Module('Notification')->Push($this->__("Configuration updated successfully."));

                // Save Configuration
                $dom->save ( $file_path );
            }
            else
            {
                App::Module('Notification')->Push($this->__("Your configuration file is not writeable($file_path)."),'Error');
            }
            $this->redirect("/developer/sys-config",'javascript');
            exit;
        }
        $this->set('sysconf',$dom);
    }

    public function uri_managerAction()
    {

    }

    public function debuggerAction()
    {
        $this->layout = 'admin';
        $this->admin_tab = 'developer';
        $this->page_title = 'System Configuration';
    }

    public function mvcmanagerAction( $action = "")
    {
    	$this->setAdminTab('developer');

        if( $action != 'create')
        {
            $mvcdata = $this->get_mvc_data($action);
            $this->set('mvcdata', $mvcdata);
        }

        $this->set('action',$action);
    }


    private function get_mvc_data( $model = "")
    {
        $models = App::Load("Helper/Utility")->getDirLising(App::__Obj('appRain_Base_Core')->model_path());

        $_mvc_data = Array();
        foreach( $models['file'] as $val )
        {
            $name = App::Load("Helper/Utility")->setFileName($val['name'])
                                               ->getName();
            if( ($model == "") || $name == $model)
            {
                $_mvc_data[$name]['model']['version']    = App::Load("Model/{$name}")->version;
                $_mvc_data[$name]['model']['db_table']   = App::Load("Model/{$name}")->db_table;
                $_mvc_data[$name]['model']['exists']     = true;
                $_mvc_data[$name]['model']['path']       = App::__Obj('appRain_Base_Core')->model_path(NULL,App::Model($name)->name);
                $_mvc_data[$name]['model']['name']       = App::Load("Model/{$name}")->name;

                $_mvc_data[$name]['model']['insteller']['exists']  = ( file_exists(App::__Obj('appRain_Base_Core')->installerPath(App::Model($name)->name))) ? true : false;

                if( file_exists(CONTROLLER_PATH . DS . $val['name'] ))
                {
                    $_mvc_data[$name]['controller']['path']     = "/development/controllers/" ;
                    $_mvc_data[$name]['controller']['exists']   = true;
                    $_mvc_data[$name]['controller']['name']     = $name;

                }
                else
                {
                    $_mvc_data[$name]['controller']['exists']   = false;
                }

                if( file_exists(VIEW_PATH . DS . $this->theme . DS . $name))
                {
                    $views = App::Load('Helper/Utility')->getDirLising( VIEW_PATH . DS . $this->theme . DS . $name);
                    $_mvc_data[$name]['view']['path'] = VIEW_PATH . DS . $this->theme . DS . $name;
                    $_mvc_data[$name]['view']['exists'] = true;

                    foreach( $views['file'] as $vnode )
                    {
                        $_mvc_data[$name]['view']['files'][] = array(
                                                                        'name' => App::Load("Helper/Utility")->setFileName($vnode['name'])->getName(),
                                                                        'url' => App::Load('Helper/Config')->baseurl( DS . $name . DS . str_replace('_','-',App::Load("Helper/Utility")->setFileName($vnode['name'])->getName())),
                                                                        'path' => "/development/view/" . $this->theme . DS . $name ,
                                                                        'file_name' => $vnode['name']
                                                                    );
                    }
                }
                else
                {
                    $_mvc_data[$name]['view']['exists'] = false;
                }
            }
        }

        // Return GROSS
        return $_mvc_data;
    }

    public function webserviceAction($className = NULL,$service = false)
    {

    	$this->layout = "blank";

        $niddles = split("[_]",$className);
        $className = "Development_Helper_Api_{$niddles[count($niddles)-1]}";

	    if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST')
	    {
	    	App::Load("Module/Webservice")->setClassName($className)
			  							  ->loadServer();
		}
		else
		{


			if ($service)
            {
				echo App::Load("Module/Webservice")->setClassName($className)
				  							  	   ->setServiceName("appRain")
				  							  	   ->showWSDL();
			}
			else
            {
				echo App::Load("Module/Webservice")->setClassName($className)
				  								   ->setServiceName("appRain")
				  								   ->showWSDLURI();
			}
		}
    }

    /*
    public function updateAction($state=NULL)
    {
        $this->setAdminTab('developer');

		$this->addons = array('versionupdater','ajaxsubmit','validation');

        $newVersion = App::Load("Module/Updatemanager")->getNewVersion();

		if(!empty($this->data))
		{
		  	try
            {
            	switch($state)
            	{
            		case  "start"	:

                                        App::Load("Module/Updatemanager")->checkappupdate($this->data['Update']['licensekey']);
            							break;
            		default			:
                						App::Load("Module/Updatemanager")->checkappupdate($this->data['Update']['licensekey']);
                                        echo App::Load("Module/Cryptography")->jsonEncode(Array("_status"=>"Redirect","_location"=>$this->baseurl("/developer/update/start")));
            	}
            }
            catch (AppException $e)
            {

                echo "Error|" . $e->getMessage();
            }
			exit;
		}

		$this->set('newversion',$newVersion);
        $this->set('state',$state);
    }
    */

    /*public function versionupdateprocessAction($state = NULl, $cmd = '')
    {
        $this->check_admin_login();
		$this->layout = "blank";

      	try
        {
            $return['state'] = isset($return['state']) ? $return['state'] : "";
          	switch($state)
           	{
           		case  "complete"	    :
           									$return = App::Load("Module/Updatemanager")->complete();
           									$this->setNextStep('complete');
                                            throw new AppException($this->__($return['message']));
            								break;
           		case  "install"	        :
           									$return = App::Load("Module/Updatemanager")->install($cmd);
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');
           									if($return['status'] == 'complete')$this->setNextStep('complete');
           									else $this->setNextStep('install');
           									throw new AppException($this->__($return['message']));
            								break;
           		case  "review"	        :
           									$return = App::Load("Module/Updatemanager")->review($cmd);
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');
           									if($return['status'] == 'complete')$this->setNextStep('install');
           									else $this->setNextStep('review');
           									throw new AppException($this->__($return['message']));
            								break;
                case  "download"	    :
           									$return = App::Load("Module/Updatemanager")->download($cmd);
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');
           									if($return['status'] == 'complete')$this->setNextStep('review');
           									else $this->setNextStep('download');
           									throw new AppException($this->__($return['message']));
            								break;
           		case  "createbackup"	:
           									$return = App::Load("Module/Updatemanager")->createfilebackup($cmd);
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');
           									if($return['status'] == 'complete')$this->setNextStep('download');
           									else $this->setNextStep('createbackup');
           									throw new AppException($this->__($return['message']));
            								break;
           		case  "preparation"	    :
           									$return = App::Load("Module/Updatemanager")->preparation($cmd);

                                            if($return['state'] == 'Failed')$this->setStatus('Failed');
                                            if($return['status'] == 'complete')$this->setNextStep('createbackup');
           									else $this->setNextStep('preparation');
           									throw new AppException($this->__($return['message']));
            								break;
           		case  "parsedefinition"	:
            								$this->setNextStep('preparation');
           									App::Load("Module/Updatemanager")->parsedefinition();
            								break;
           		case  "getdefinition"	:
            								$result = App::Load("Module/Updatemanager")->getdefinition();
            								break;
            	default					:
                							$result = Array("status"=>"processComplete","message"=>"Repository updates successfully. You may navigate away this page.");
                							break;
           	}


            echo App::Load("Module/Cryptography")->jsonEncode($result);
        }
        catch (AppException $e)
        {
        	$message = ($this->getStatus()) ? $this->getStatus() : "message";
        	$nextstep = ($this->getNextStep()) ? $this->getNextStep() : "";
        	echo App::Load("Module/Cryptography")->jsonEncode(Array("nextstep"=>$nextstep,"status"=>$message,"message"=>$e->getMessage()));
        }
    }*/

    public function clearcacheAction()
    {
        $this->setAdminTab('developer');

        $message = "";
        $cacheAllDef = App::Load("Module/Developer")->setCacheAllDef();

        $def = Array(""=>"All");
        foreach($cacheAllDef as $key => $val )
        {
            $def[$key] = $val['title'];
        }

        if(!empty($this->data))
        {
            App::Load("Module/Developer")->setCacheType($this->data['Cache']["type"])
                                         ->clearCache();

            App::Module('Notification')->Push($this->__("Temporary Cache has been cleared successfully."));

        }

        $this->set('cacheAllDef',$def);
    }

    public function languageswitchAction($code="")
    {
        App::Module('Language')->setDefault($code);
        $this->redirect("/developer/language");
        exit;
	}


    /**
     * Manage Language
     */
    public function languageAction( $lang_file = NULL)
    {
        $this->setAdminTab('developer');

        if( !empty($_POST))
        {
            $_dom = new DomDocument();
            $_language = $_dom->createElement ('Language');
            $_language = $_dom->appendChild ($_language);

            // Base Section
            $_base = $_dom->createElement ('base');
            $_base = $_language->appendChild ($_base);

            $_code = $_dom->createElement ('code');
            $_code->nodeValue = $_POST['data']['code'];
            $_base->appendChild ($_code);

            $_title = $_dom->createElement ('title');
            $_title->nodeValue = $_POST['data']['title'];
            $_base->appendChild ($_title);


            // Language values
            $_langs = $_dom->createElement ('langs');
            $_langs = $_language->appendChild ($_langs);

            foreach($_POST['data']['lang'] as $order => $lang)
            {
                if( $lang['key'] != "" )
                {
                    $_lang = $_dom->createElement ('lang');
                    $_lang = $_langs->appendChild ($_lang);

                    $_key = $_dom->createElement ('key');
                    $_key->nodeValue =$lang['key'];
                    $_key = $_lang->appendChild ($_key);

                    $_val = $_dom->createElement ('val');
                    $_val->nodeValue =$lang['value'];
                    $_key = $_lang->appendChild ($_val);
                }
            }

			$path = App::Module('Language')->lanuagePaths(App::Helper('utility')->getName($lang_file));
            $_dom->save($path . "/{$lang_file}");
        }

		$paths = App::Module('Language')->lanuagePaths();
        $lang_fiels = App::Load('Helper/Utility')->getDirLising($paths);
        $this->set('lang_fiels',$lang_fiels['file']);

        if(isset($lang_file))
        {
			$path = App::Module('Language')->lanuagePaths(App::Helper('utility')->getName($lang_file));

            $lan_xml = simplexml_load_file($path . "/{$lang_file}");
            $this->set('xml',$lan_xml);
            $this->set('lang_file',$lang_file);
        }
    }

    public function debug_logAction($mode='file', $action = NULL)
    {
        $this->setAdminTab('developer');

        if($mode == 'file')
        {
            if( $action == 'clear') App::Helper('Log')->clear('file');

            $logData = App::Helper('Log')->readFullLog();
            $this->set('logData',$logData);
        }
        else
        {
            if( $action == 'clear') App::Model('Log')->delete();

            $logData = App::Model('Log')->paging(1,50);
            $this->set('logData',$logData);
        }

        $this->set('mode',$mode);
    }

    public function componentsAction($classname=null,$action=null)
    {
        $this->setAdminTab('component');
        $paginglink = isset($this->get['page']) ? "?page={$this->get['page']}": "";

        if($action == 'changestatus')
        {
           App::Component($classname)->chnageStatus();

           if(App::Component($classname)->status() == appRain_Base_component::STATUS_ACTIVE)App::Module('Notification')->Push("'{$classname}' Component Deactivated successfully");
           else App::Module('Notification')->Push("'{$classname}' Component Activated successfully");

		   App::Module("Developer")->clearCache();
           $this->redirect("/developer/components/{$paginglink}#{$classname}");
           exit;
        }
		else if($action == 'remove')
		{
			if(App::Component($classname)->status() == appRain_Base_component::STATUS_ACTIVE)App::Component($classname)->chnageStatus();
            $obj =  App::Module('Universal_Installer')
                       ->setResourcePath( COMPONENT_PATH . DS . $classname)
                       ->Uninstall();

            App::Module('Notification')->Push("'{$classname}' Component removed successfully");
			App::Module("Developer")->clearCache();
			$this->redirect("/developer/components/{$paginglink}#{$classname}");
    		exit;
		}
		else if($action=='install')
		{
			$this->install_component();

			App::Module("Developer")->clearCache();

			App::Module('Notification')->Push("Component removed successfully");
			App::Module("Developer")->clearCache();
			$this->redirect("/developer/components");
			exit;
		}

		$componentlist = App::Load("Helper/Utility")->multiArraySort(app::__def()->getComponentList(),'name','ASC');
        $componentlist = App::Load("Helper/Utility")->array_paginator($componentlist,array('limit'=>"10"));
        $this->set('componentlist',$componentlist);

        $this->set('paginglink',$paginglink);
		$this->set('action',$action);
    }

	private function install_component()
	{

		$this->setAdminTab('component');
		$message = "";
        $error = "";
		if(!empty($this->data))
		{
			if(!is_writable(COMPONENT_PATH . DS))
			{
				App::Module('Notification')->Push("Component path is not writeable :" . COMPONENT_PATH . DS,'Error');
			}
			else if($this->data['Component']['resourcefile']['tmp_name'] == "")
			{
                App::Module('Notification')->Push("Select a component file please.. ",'Error');
			}
			else
			{
				$obj =  App::Module('Universal_Installer')
                           ->setSourceAutoDelete(true)
                           ->setDefaultInstallationPath(COMPONENT_PATH)
                           //->setResourcePath($filePath)
                           ->upload($this->data['Component']['resourcefile'])
                           ->Install();
                if(empty($obj->errors))App::Module('Notification')->Push('Component installed successfully');
                else App::Module('Notification')->Push($obj->errors,'Error');
			}

            $this->redirect("/developer/components");
            exit;
		}

	}
}
